package cn.nbt.busManage.service.impl;

import cn.nbt.busManage.dao.mapper.BusMapper;
import cn.nbt.busManage.model.dto.BusDto;
import cn.nbt.busManage.model.dto.DriverDto;
import cn.nbt.busManage.model.dto.RouteDto;
import cn.nbt.busManage.model.entity.Bus;
import cn.nbt.busManage.model.entity.Driver;
import cn.nbt.busManage.model.entity.Route;
import cn.nbt.busManage.dao.repository.BusRepository;
import cn.nbt.busManage.dao.repository.DriverRepository;
import cn.nbt.busManage.dao.repository.RouteRepository;
import cn.nbt.busManage.service.BusService;
import cn.nbt.busManage.service.RouteService;
import jakarta.persistence.EntityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
@Transactional
public class IBusService implements BusService {
    @Autowired
    private BusRepository busRepository;

    @Autowired
    private RouteRepository routeRepository;

    @Autowired
    private DriverRepository driverRepository;

    @Autowired
    private RouteService routeService;

    @Autowired
    private EntityManager entityManager;

    @Autowired
    private BusMapper busMapper;

    /**
     * 保存车辆信息
     * @param busDto 车辆信息
     */
    @Override
    public void save(BusDto busDto) {
        Bus bus = new Bus();
        bus.setCapacity(busDto.getCapacity());
        bus.setModel(busDto.getModel());
        bus.setLastMaintenanceDate(busDto.getLastMaintenanceDate());
        bus.setLicensePlate(busDto.getLicensePlate());
        bus.setNextInspectionDate(busDto.getNextInspectionDate());
        bus.setStatus(busDto.getStatus());
        routeRepository.findById(busDto.getRoute().getId()).ifPresent(bus::setRoute);
        List<Driver> drivers = new ArrayList<>();
        for (DriverDto driverDto : busDto.getDrivers()) {
            driverRepository.findById(driverDto.getId()).ifPresent(drivers::add);
        }
        bus.setDrivers(drivers);
       /* RouteDto routeDto = busDto.getRoute();
        if (routeDto != null && routeDto.getId() != null){
            Route route = entityManager.find(Route.class, routeDto.getId());
            bus.setRoute(route);
        }
        List<DriverDto> driverDtoList = busDto.getDrivers();
        if(driverDtoList != null) {
            ArrayList<Driver> drivers = new ArrayList<>();
            for (DriverDto dto : driverDtoList){
                Driver driver = entityManager.find(Driver.class, dto.getId());
                drivers.add(driver);
            }
            bus.setDrivers(drivers);
        }
        entityManager.persist(bus);*/
        busRepository.save(bus);
//        entityManager.close();
    }

    /**
     * 将bus转换为busDto
     * @param bus 车辆
     * @return 车辆信息
     */
    private BusDto busToBusDto(Bus bus) {
        BusDto busDto = new BusDto(bus);
        if(bus.getRoute() != null) {
            RouteDto routeDto = routeService.findById(bus.getRoute().getId());
            if(routeDto != null){
                busDto.setRoute(routeDto);
            }
        }
        if(bus.getDrivers() != null) {
            bus.getDrivers().forEach(driver -> {
                busDto.getDrivers().add(new DriverDto(driver));
            });
        }
        return busDto;
    }

    /**
     * 查询所有车辆
     * @return 车辆信息
     */
    @Override
    public List<BusDto> findAll() {
        Iterable<Bus> all = busRepository.findAll();
        ArrayList<BusDto> busDtos = new ArrayList<>();
        for (Bus bus : all) {
            BusDto busDto = new BusDto(bus);
            busDtos.add(busDto);
        }
        return busDtos;
    }

    /**
     * 根据id查询车辆
     * @param id 车辆id
     * @return 车辆信息
     */
    @Override
    public BusDto findById(int id) {
        Bus bus = busRepository.findById(id).orElse(null);
        if (bus == null) {
            return null;
        }
        return busToBusDto(bus);
    }

    /**
     * 更新车辆信息
     * @param busDto 车辆信息
     */
    @Override
    public void update(BusDto busDto) {
        Bus bus = new Bus();
        bus.setId(busDto.getId());
        bus.setCapacity(busDto.getCapacity());
        bus.setModel(busDto.getModel());
        bus.setLastMaintenanceDate(busDto.getLastMaintenanceDate());
        bus.setLicensePlate(busDto.getLicensePlate());
        bus.setNextInspectionDate(busDto.getNextInspectionDate());
        bus.setStatus(busDto.getStatus());
        RouteDto routeDto = busDto.getRoute();
        if (routeDto != null && routeDto.getId() != null){
            Route route = entityManager.find(Route.class, routeDto.getId());
            bus.setRoute(route);
        }
        List<DriverDto> driverDtoList = busDto.getDrivers();
        if(driverDtoList != null) {
            ArrayList<Driver> drivers = new ArrayList<>();
            for (DriverDto dto : driverDtoList){
                Driver driver = entityManager.find(Driver.class, dto.getId());
                drivers.add(driver);
            }
            bus.setDrivers(drivers);
        }
        entityManager.merge(bus);
    }

    /**
     * 删除车辆
     * @param id 车辆id
     */
    @Override
    @Transactional("mybatisTransactionManager")
    public void delete(int id) {
        busMapper.deleteBusDriverByBusId(id);
        busMapper.deleteById(id);
    }

    /**
     * 根据车牌号查询车辆
     * @param licensePlate 车牌号
     * @return 车辆信息
     */
    @Override
    public BusDto findByLicensePlate(String licensePlate) {
        Bus bus = busRepository.findByLicensePlate(licensePlate);
        if(bus == null) {
            return null;
        }
        return busToBusDto(bus);
    }

    @Override
    public boolean ifFindByLicensePlate(String licensePlate) {
        Bus bus = busRepository.findByLicensePlate(licensePlate);
        if(bus == null) {
            return false;
        }
        return true;
    }

    /**
     * 根据站点查询车辆
     * @param pointName 站点
     * @return 车辆信息
     */
    @Override
    public List<BusDto> findByPoint(String pointName) {
//        根据站点查询路线
        List<RouteDto> routeDtos = routeService.findRouteByPointName(pointName);
        ArrayList<BusDto> busDtos = new ArrayList<>();
        for (RouteDto routeDto : routeDtos) {
            List<Bus> buses = busRepository.findByRouteId(routeDto.getId());
            for (Bus bus : buses) {
                BusDto busDto = busToBusDto(bus);
                busDtos.add(busDto);
            }
        }
        return busDtos;
    }
}
